package com.example.myapplication.TouchDemo;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

import androidx.appcompat.widget.AppCompatImageView;

public class ScalaImageView extends AppCompatImageView implements ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener {
    ScaleGestureDetector mScaleGestureDetector;
    Matrix mScaleMatrix = new Matrix();

    float  initScale = 1.0f;

    static final float  SCALE_MAX = 6.0f;

    float[] matrixValues = new float[9];

    public ScalaImageView(Context context, AttributeSet attrs) {
        super(context);
        mScaleGestureDetector = new ScaleGestureDetector(context,this);
//        super.setScaleType(ScaleType.MATRIX);
        this.setOnTouchListener(this);
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float scale = getScale();
        float scaleFactor = detector.getScaleFactor();
        if((scale<SCALE_MAX&&scaleFactor>1.0f)||(scale>initScale&&scaleFactor<1.0f)){
            if(scaleFactor*scale<initScale){
                scaleFactor = initScale/scale;
            }

            if(scaleFactor*scale>initScale){
                scaleFactor = SCALE_MAX/scale;
            }
        }
//        mScaleMatrix.postScale(scaleFactor,scaleFactor,getWidth()/2,getHeight()/2);

        mScaleMatrix.postScale(scaleFactor,scaleFactor,detector.getFocusX()/2,detector.getFocusY()/2);
        checkBorderAndCenterWhenScale();

        setImageMatrix(mScaleMatrix);
        return true;
    }

    private void checkBorderAndCenterWhenScale() {
        RectF rectF = getMatrixRectF();
        float deltaX = 0;
        float deltaY = 0;

        int width = getWidth();
        int height = getHeight();

        if(rectF.width()>=width){
           if(rectF.left>0){
               deltaX = -rectF.left;
           }
           if(rectF.right<width){
               deltaX = width-rectF.right;
           }
            if(rectF.height()>height){
                if(rectF.top>0){
                    deltaY = -rectF.top;
                }
                if(rectF.top<height){
                    deltaY = height-rectF.bottom;
                }
            }

            if(rectF.width()<width){
                deltaX = width*0.5f - rectF.right+0.5f*rectF.width();
            }
            if(rectF.height()<height){
                deltaX = height*0.5f - rectF.bottom+0.5f*rectF.height();
            }

            mScaleMatrix.postScale(deltaX,deltaY);


        }
    }

    private float getScale() {
        mScaleMatrix.getValues(matrixValues);
        return matrixValues[Matrix.MSCALE_X];
    }

    private RectF getMatrixRectF(){
        Matrix matrix = mScaleMatrix;
        RectF rect = new RectF();
        Drawable d = getDrawable();
        if(null != d){
            rect.set(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
            matrix.mapRect(rect);
        }
        return rect;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        mScaleGestureDetector.onTouchEvent(event);
        return true;
    }
}
